#!/usr/bin/perl

use strict;
use warnings;

# tell Perl where to find MozComics package
BEGIN { push @INC, "/home/mozcomic/scrapers/"; }

use MozComics::JSON;
use MozComics::MySQL;

use LWP::Simple;
use DateTime;
use DateTime::Format::Strptime;
use HTML::Entities qw(decode_entities);

# initialize comic object
my $guid = 'a0726a75-3aac-4be4-ae15-a903bddc9eeb';
#my $comic = MozComics::JSON->new($guid);
my $comic = MozComics::MySQL->new($guid);
my $comicName = $comic->getName();

my $lastStripRow = $comic->getLastStrip();
my $lastStrip = 0;
my $archiveUrl = 'http://xkcd.com/archive/';
my $archivePage = ''; # don't necessarily download archive page every time

my $dateParser = new DateTime::Format::Strptime(
	pattern => '%F',
	locale  => 'en_US'
);

# special cases for titles
my %specialTitles = (
	259 => 'Cliched Exchanges',
	472 => 'House of Pancakes',
  783 => 'I Don\'t Want Directions'
);

# scrape information from a page
sub scrapePage {
	my $id = shift(@_) or die "$comicName: id not passed to scrapePage";
	my $url = shift(@_) or die "$comicName: url not passed to scrapePage";
	my $page = shift(@_) or die "$comicName: page not passed to scrapePage";
	my $data = {};
	$data->{url} = $url;
	my @scraped;

	# scrape 'title', 'image', and 'extra'
	my $regex = qr/\<img src="http:\/\/imgs.xkcd.com\/comics\/(.+?)" title="(.+?)" alt="(.+?)" \/\>/;
	@scraped = $comic->scrapeUnique($page, $regex);
	$data->{image} = "http://imgs.xkcd.com/comics/$scraped[0]";
	$data->{extra} = "{\"mouseover\":\"$scraped[1]\"}";
	$data->{title} = ($specialTitles{$id} or $scraped[2]);

	# scrape 'strip' value
	if($archivePage ne '') {
		my $stripRegex = qr/\<a href="\/$id\/" title="(.*?)"\>(.*?)\<\/a\>/;
		@scraped = $comic->scrapeUnique($archivePage, $stripRegex);

		if($data->{title} ne $scraped[1]) {
			if(not defined $specialTitles{$id}) {
				die "$comicName: archive page title different than strip page title";
			}
		}

		my $dateString = $scraped[0];
		my $date = $dateParser->parse_datetime($dateString)
		           or die "$comicName: could not parse date ($dateString)";
		my $strip = $date->epoch();

		if($strip <= $lastStrip) {
			$strip = $lastStrip; #die "$comicName: $title is out of order?";
		}
		$strip += 1000;
		$lastStrip = $strip;
		$data->{strip} = $strip;
	}

	return $data;
}


$lastStripRow->{url} =~ /xkcd\.com\/(\d+)\//
                       or die "$comicName: last strip url malformed?";
my $lastId = int($1);
my $stripPage = get($lastStripRow->{url})
                or die "$comicName: last page url not found";
my $lastStripData = scrapePage($lastId, $lastStripRow->{url}, $stripPage);

$comic->assertStripsEqual($lastStripData, $lastStripRow);

if(not($stripPage =~ /\<a href="(#|\/(\d+)\/)" accesskey="n"\>Next \&gt;\<\/a\>/)) {
	die "$comicName: next link format changed";
}

$lastStrip = $lastStripRow->{strip};
while($stripPage =~ /\<a href="\/(\d+)\/" accesskey="n"\>Next \&gt;\<\/a\>/) {
	my $id = int($1);
	my $url = "http://xkcd.com/$id/";
	$stripPage = get($url) or die "$comicName: next strip page not found";

	# only download archive page if a new strip is found
	if($archivePage eq '') {
		$archivePage = get($archiveUrl) or die "$comicName: archive page not found";
	}

	#print "$url\n";
	$comic->addStrip(scrapePage($id, $url, $stripPage));
}

$comic->commit();

